#pragma once

#include <iostream>
#include <queue>
#include <pthread.h>
#include <functional>
#include <cstdio>
#include <cstring>

using std::cerr;
using std::cout;
using std::endl;

const std::string oper = "+-*/%";
int my_math(int x, int y, char op)
{
    int result = 0;
    switch (op)
    {
    case '+':
        // return x + y;//return 不需要break
        result = x + y;
        break;
    case '-':
        // return x - y;
        result = x - y;

        break;
    case '*':
        // return x * y;
        result = x * y;

        break;
    case '/':
    {
        if (y == 0)
        {
            cerr << "div zero error!" << endl;
            result = -1;
        }
        else
            result = x / y;
    }
    break;
    case '%':
    {

        if (y == 0)
        {
            cerr << "mod zero error!" << endl;
            result = -1;
        }
        else
            result = x % y;

        // return x % y;
    }
    break;
    default:
        break;
    }
    return result;
}

class CalTask
{
    using func_t = std::function<int(int, int, char)>; // 这里也要加上一个char，不然回调函数和Main文件里面的my_math函数参数对不上
    // typedef function<int(int, int)> func_t;

public:
    CalTask()
    {
    }
    CalTask(int x, int y, char op, func_t func)
        : _x(x),
          _y(y),
          _op(op),
          _callback(func)
    {
    }
    // int operator()() // 仿函数
    std::string operator()()
    {
        int result = _callback(_x, _y, _op);
        char buffer[1024];
        snprintf(buffer, sizeof(buffer), "%d %c %d = %d", _x, _op, _y, result);
        return buffer;
        // return result;
    }
    std::string TaskToString()
    {
        char buffer[1024];
        snprintf(buffer, sizeof(buffer), "%d %c %d = ?", _x, _op, _y);
        return buffer;
    }
    ~CalTask()
    {
    }

private:
    int _x;
    int _y;
    char _op;
    func_t _callback;
};

void savethread(const std::string &massage)
{
    const std::string target = "./log.tex";
    FILE *fp = fopen(target.c_str(), "a+");
    if (fp == nullptr)
    {
        cerr << "fopen file error!" << endl;
        return;
    }
    fputs(massage.c_str(), fp);
    fprintf(fp, "\n");
    fclose(fp);
}

class SaveTask
{
    typedef std::function<void(const std::string &)> func_t;

public:
    SaveTask()
    {
    }
    SaveTask(const std::string &massage, func_t func)
        : _massage(massage),
          _func(func)
    {
    }
    ~SaveTask()
    {
    }
    void operator()()
    {
        _func(_massage);
    }

private:
    std::string _massage;
    func_t _func;
};